package com.fpd.tools;

import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;

/**
 * Double 工具类
 */
public class DoubleFormatUtil {
    /**
     * 字符串转Double
     *
     * @param doubleString double类型的字符串
     * @return
     */
    public static double strToDouble(String doubleString) {
        try {
            return Double.parseDouble(doubleString);
        } catch (Exception e) {
            return 0.0;
        }
    }

    /**
     * @param d double类型的字符串
     * @return 四舍五入后保留2位小数的值
     */
    public static double getRoundHalfUpDouble(double d) {
        return getRoundHalfUpDouble(String.valueOf(d));
    }

    /**
     * 对于一个double 型的字符串进行四舍五入和保留两位小数处理,如果最后一位小数位为0,则默认不显示
     *
     * @param doubleString double类型的字符串
     * @return 四舍五入后保留2位小数的值
     */
    public static double getRoundHalfUpDouble(String doubleString) {
        try {
            BigDecimal b = new BigDecimal(doubleString);
            return b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        } catch (Exception e) {
            return 0.0;
        }
    }

    /**
     * 对于一个double 型的字符串进行四舍五入和保留两位小数处理,如果最后一位小数位为为0,则仍然显示。
     *
     * @param doubleString double类型的字符串
     * @return
     */
    public static String getRoundHalfUpDoubleStr(String doubleString) {
        try {
            double tempDoubleString = getRoundHalfUpDouble(doubleString);
            return String.format("%.2f", tempDoubleString);
        } catch (Exception e) {
            return doubleString;
        }
    }

    /**
     * 精确的double类型的字符串加法运算
     *
     * @param doubleStr1 被加数
     * @param doubleStr2 加数
     * @return 两个参数的和
     */
    public static double add(String doubleStr1, String doubleStr2) {
        if (StringUtils.isEmpty(doubleStr1) || StringUtils.isEmpty(doubleStr2)) {
            return 0;
        }
        try {
            BigDecimal b1 = new BigDecimal(doubleStr1);
            BigDecimal b2 = new BigDecimal(doubleStr2);
            return b1.add(b2).doubleValue();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 对double 类型的浮点数进行加法运算
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public static double add(double v1, double v2) {
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.add(b2).doubleValue();
    }

    /**
     * 对double 类型的浮点数进行加法运算
     * @param scale 保留小数位
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public static double add(int scale, double v1, double v2) {
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 多个数相加
     *
     * @param arg
     * @return
     */
    public static double add(double... arg) {
        double total = 0;
        for (double d : arg) {
            total = add(total, d);
        }
        return total;
    }

    /**
     * 多个数相加
     * @param scale 保留小数位
     * @param arg
     * @return
     */
    public static double add(int scale, double... arg) {
        double total = 0;
        for (double d : arg) {
            total = add(scale, total, d);
        }
        return total;
    }

    /**
     * 对double 类型的浮点数进行减法运算。
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static double subtract(double v1, double v2) {
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 对double 类型的浮点数进行减法运算。
     * @param scale 保留小数位
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static double subtract(int scale, double v1, double v2) {
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 多个数相减
     *
     * @param arg
     * @return
     */
    public static double subtract(double... arg) {
        double total = 0;
        for (int i = 0; i < arg.length; i++) {
            if (i == 0) {
                total = arg[i];
                continue;
            }
            total = subtract(total, arg[i]);
        }
        return total;
    }

    /**
     * 多个数相减
     *
     * @param arg
     * @return
     */
    public static double subtract(int scale, double... arg) {
        double total = 0;
        for (int i = 0; i < arg.length; i++) {
            if (i == 0) {
                total = arg[i];
                continue;
            }
            total = subtract(scale, total, arg[i]);
        }
        return total;
    }

    /**
     * 对double 类型的浮点数进行乘法运算。
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static double multiply(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 对double 类型的浮点数进行乘法运算。
     * @param scale 保留小数位
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static double multiply(int scale, double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 多个数相乘
     *
     * @param arg
     * @return
     */
    public static double multiply(double... arg) {
        double total = 0;
        for (int i = 0; i < arg.length; i++) {
            if (i == 0) {
                total = arg[i];
                continue;
            }
            total = multiply(total, arg[i]);
        }
        return total;
    }

    /**
     * 多个数相乘
     * @param scale
     * @param arg
     * @return
     */
    public static double multiply(int scale, double... arg) {
        double total = 0;
        for (int i = 0; i < arg.length; i++) {
            if (i == 0) {
                total = arg[i];
                continue;
            }
            total = multiply(scale, total, arg[i]);
        }
        return total;
    }

    /**
     * 两个数相除，默认保留2位小数
     *
     * @param v1
     * @param v2
     * @return
     */
    public static double divide(double v1, double v2) {
    	return divide(v1, v2, 2);
    }

    /**
     * 对double 类型的浮点数进行除法运算。当发生除不尽的情况时,由scale参数指
     * 定精度,以后的数字四舍五入。
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public static double divide(double v1, double v2, int scale) {
    	if (0 == v2) {
    		return 0;
    	}
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}
